package com.erdos.message.entity;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.builder.ToStringBuilder;

import com.erdos.message.command.ServiceInvocation;


public class MessageChannelVO implements Serializable {
	private static final long serialVersionUID = -5997466717286966006L;
	
	private String destination;
	
	/**
	 * the same Destination must refer to the same client id.
	 */
	private String clientId;
	
	/**
	 * key: messageTypeId <br>
	 * value:ServiceInvocation instance
	 */
	private Map<String, ServiceInvocation> invocationMap;
	
	/**
	 * key: business FQN of entity class <br>
	 * value: messageTypeId
	 */
	private Map<String, String> entityMap;
	
	/**
	 * true indecates this instance associated MessageListener is running, false otherwise.
	 */
	private boolean listenerRunning=false;
	
	private boolean waived;
	
	private String serverName;
	/**
	 * indicates the status of current Listener
	 */
	private String listenerStatus;
	
	public MessageChannelVO() {
		this.entityMap=new HashMap<String, String>();
		this.invocationMap=new HashMap<String, ServiceInvocation>();
	}
	/**
	 * @return the destination
	 */
	public String getDestination() {
		return destination;
	}
	/**
	 * @param destination the destination to set
	 */
	public void setDestination(String destination) {
		this.destination = destination;
	}
		
	public ServiceInvocation getServiceInvocation(String msgTypeId) {
		return this.invocationMap.get(msgTypeId);
	}
	/**
	 * @param invocationMap the invocationMap to set
	 */
	public void addInvocationMap(String msgTypeId, ServiceInvocation invocation) {
		this.invocationMap.put(msgTypeId, invocation);
	}
	
	public void addEntityMap(String entity, String msgTypeId) {
		this.entityMap.put(entity, msgTypeId);
	}
	/**
	 * key: entity <br>
	 * value: messageTypeId
	 * @return
	 */
	public Map<String, String> getEntityMap() {
		return Collections.unmodifiableMap(this.entityMap);
	}
	
	public String getMessageTypeIdByEntity(String entity) {
		return this.entityMap.get(entity);
	}
	
	/**
	 * @return the clientId
	 */
	public String getClientId() {
		return clientId;
	}
	/**
	 * @param clientId the clientId to set
	 */
	public void setClientId(String clientId) {
		this.clientId = clientId;
	}	
	
	/**
	 * key: messageTypeId <br>
	 * value:ServiceInvocation instance
	 * @return the invocationMap an unmodified Map
	 */
	public Map<String, ServiceInvocation> getInvocationMap() {
		return Collections.unmodifiableMap( invocationMap);
	}
	
	public Collection<ServiceInvocation> getServiceInvocations() {
		return this.invocationMap.values();
	}
	
	public boolean containsMessageTypeId(String msgTypeId) {
		return this.invocationMap.containsKey(msgTypeId);
	}
	
	public boolean isListenerRunning() {
		return listenerRunning;
	}
	public void setListenerRunning(boolean listenerRunning) {
		this.listenerRunning = listenerRunning;
	}
	
	public boolean isWaived() {
		return waived;
	}
	public void setWaived(boolean waived) {
		this.waived = waived;
	}
	
	public String getServerName() {
		return serverName;
	}
	public void setServerName(String serverName) {
		this.serverName = serverName;
	}	
	
	/**
     * @return the listenerStatus
     */
    public String getListenerStatus() {
        return listenerStatus;
    }
    /**
     * @param listenerStatus the listenerStatus to set
     */
    public void setListenerStatus(String listenerStatus) {
        this.listenerStatus = listenerStatus;
    }
    /* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 13;
		result = prime * result
				+ ((destination == null) ? 0 : destination.hashCode());
		return result;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
			
		if (obj == null) {
			return false;
		}
			
		if (!(obj instanceof MessageChannelVO)) {
			return false;
		}
			
		final MessageChannelVO other = (MessageChannelVO) obj;
		if (destination == null) {
			if (other.destination != null) {
				return false;
			}				
		} else if (!destination.equals(other.destination)) {
			return false;
		}
			
		return true;
	}
	
	public String toString() {
		return new ToStringBuilder(this).append(this.destination)
			.append(this.entityMap).append(this.clientId).append(this.invocationMap).toString();
	}
}
